from server.pao_python.pao.service.data.mongo_db import MongoService, MongoFilter, C, N, F, as_date
from ...service.mongo_bill_service import MongoBillFilter
from ...service.buss_pub.personnel_organizational import UserType
from enum import Enum
from server.pao_python.pao.service.security.security_utility import SecurityConstant, get_current_account_id


class borrowLoan(Enum):
    income = '收入'
    output = '支出'


class fundType(Enum):
    fund = '慈善资金'


class DisplayNyService(MongoService):
    '''测试服务'''

    bus_area = '南海'  # 业务区域为南海
    financial_account_record = 'PT_Financial_Account_Record_Directional'
    current_year = 2019

    def __init__(self, db_addr, db_port, db_name, db_user, db_pwd, inital_password, session):
        self.db_addr = db_addr
        self.db_port = db_port
        self.db_name = db_name
        self.db_user = db_user
        self.db_pwd = db_pwd
        self.inital_password = inital_password
        self.session = session

    ####################### 公共部分 ##############################
    def set_session_area(self):
        '''设置session的区域id'''
        account_id = get_current_account_id(self.session)
        _filter = MongoBillFilter()
        _filter.match_bill(C('account_id') == account_id)\
               .lookup_bill('PT_Administration_Division', 'admin_area_id', 'id', 'div_info')\
               .graph_lookup('PT_Administration_Division', '$div_info.parent_id', 'parent_id', 'id', 'all_admin')\
               .unwind('all_admin')\
               .inner_join_bill('PT_Business_Area', 'all_admin.id', 'admin_id', 'area_info')
        res = self.query(_filter, 'PT_User')
        self.session[SecurityConstant.area] = res[0]['area_info']['id']
        return res[0]['area_info']['id']

    def get_current_user_area_id(self):
        '''通过session获取当前登录用户的区域id'''
        if SecurityConstant.area in list(self.session.keys()):
            return self.session[SecurityConstant.area]
        else:
            res = self.set_session_area()
            return res

    def ___create_list(self, obj_list):
        '''将数据转成列表
        eg : obj_list = [{'y':a},{'y':b},{'y':c}] >> [a,b,c]
        '''
        new_list = []
        for obj in obj_list:
            tep = list(obj.values())
            new_list.append(tep[0])
        return new_list

    def __org_area(self):
        '''找到某业务区域内的所有user信息'''
        division_id = self.get_current_user_area_id()
        _filter = MongoBillFilter()
        _filter.match(C('id') == division_id)\
               .inner_join('PT_Administration_Division', 'admin_id', 'id', 'admin_info')\
               .graph_lookup('PT_Administration_Division', '$admin_info.parent_id', 'id', 'parent_id', 'all_admin')\
               .project({'admin_id': '$all_admin.id'})\
               .unwind('admin_id')\
               .inner_join_bill('PT_User', 'admin_id', 'admin_area_id', 'user_info')
        return _filter

    def __elder_group_by_age(self, _filter):
        _filter.add_fields({'age': ((F('year')-self.current_year)*(-1)).f})\
               .add_fields({'age_range': self.ao.switch([self.ao.case(((F('age') >= 50) & (F('age') < 60)), '50-59'),
                                                         self.ao.case(
                                                             ((F('age') >= 60) & (F('age') < 70)), '60-69'),
                                                         self.ao.case(
                                                             ((F('age') >= 70) & (F('age') < 80)), '70-79'),
                                                         self.ao.case(
                                                             ((F('age') >= 80) & (F('age') < 90)), '80-89'),
                                                         self.ao.case(((F('age') >= 90) & (F('age') < 100)), '90-99')], '100以上')})
        return _filter

    def _group_by_date(self, _filter, col_name, date_unit):
        '''按date进行分组统计时，对日期进行处理，处理后数据存为新的一列
        Args :
            col_name:待处理的日期列名
            date_unit：分组的日期粒度，三个值可选：日，周，月 [暂时仅支持日和月]
        '''
        if date_unit == '日':
            _filter.add_fields(
                {'new_date': self.ao.date_to_string(col_name, '%Y-%m-%d')})
        elif date_unit == '月':
            _filter.add_fields(
                {'new_date': self.ao.date_to_string(col_name, '%Y-%m')})
        return _filter

    def ___org_area_welfare(self):
        '''获取指定业务区域内的福利院'''
        _filter = self.__org_area()
        _filter.match(C('user_info.personnel_type') == UserType.Organizational)\
               .match(C('user_info.organization_info.personnel_category') == '福利院')
        return _filter

    def _group_by_date(self, _filter, col_name, date_unit):
        '''按date进行分组统计时，对日期进行处理，处理后数据存为新的一列
        Args :
            col_name:待处理的日期列名
            date_unit：分组的日期粒度，三个值可选：日，周，月 [暂时仅支持日和月]
        '''
        if date_unit == '日':
            _filter.add_fields(
                {'new_date': self.ao.date_to_string(col_name, '%Y-%m-%d')})
        elif date_unit == '月':
            _filter.add_fields(
                {'new_date': self.ao.date_to_string(col_name, '%Y-%m')})
        return _filter

    def cop_statistics_donation_income_quantity(self, condition, page, count):
        '''慈善资金收入类型对比'''
        _filter = self.__org_area()
        _filter.match_bill((C('borrow_loan') == borrowLoan.income.value) & (C('fund_type') == fundType.fund.value))\
            .group({'x': '$fund_type'}, [{'y': self.ao.summation('$fund_total')}])\
            .sort({'y': -1})
        res = self.query(_filter, self.financial_account_record)
        return res

    def cop_statistics_donor_income_top10_quantity(self, condition, page, count):
        '''慈善资金捐赠榜（TOP10）'''
        _filter = self.__org_area()
        _filter.match_bill(C('borrow_loan') == borrowLoan.income.value & C('fund_type') == fundType.fund.value)\
            .group({'x': '$user_id'}, [{'y': self.ao.summation('$fund_total')}])\
            .sort({'y': -1})\
            .limit(10)
        res = self.query(_filter, self.financial_account_record)
        return _filter

    def cop_statistics_item_income_top10_quantity(self, condition, page, count):
        '''慈善项目收入金额排名'''
        _filter = self.__org_area()
        _filter.match_bill(C('borrow_loan') == borrowLoan.income.value & C('fund_type') == fundType.fund.value)\
            .group({'x': '$fund_use_direction'}, [{'y': self.ao.summation('$fund_total')}])\
            .sort({'y': -1})\
            .limit(10)
        print('<<<<<<<<<<<<<', _filter.filter_objects)
        res = self.query(_filter, self.financial_account_record)
        return _filter

    def cop_statistics_org_use_amount_quantity(self, condition, page, count):
        '''福利院使用慈善金额统计'''
        _filter = self.__org_area()
        _filter.match_bill(C('borrow_loan') == borrowLoan.output.value & C('fund_type') == fundType.fund.value)\
            .group({'x': '$fund_use_direction'}, [{'y': self.ao.summation('$fund_total')}])\
            .sort({'y': -1})\
            .limit(10)
        res = self.query(_filter, self.financial_account_record)
        return _filter

    def cop_statistics_type_use_amount_quantity(self, condition, page, count):
        '''慈善资金支出类型对比'''
        keys = ['user_id']
        values = self.get_value(condition, keys)
        _filter = MongoBillFilter()
        _filter.match_bill(C('user_id') == values['user_id'] & C('fund_use_direction') == '支出' & C('fund_use_direction') == '慈善基金')\
               .group({'x': 'fund_total'}, [{'y': self.ao.summation(1)}])
        res = self.query(_filter, self.financial_account_record)
        return _filter

    def cop_statistics_donor_use_amount_top10_quantity(self, condition, page, count):
        '''慈善资金应用榜（TOP10）'''
        _filter = MongoBillFilter()
        _filter.lookup_bill('PT_User', 'user_id', 'id', 'user_info')\
            .match_bill(C('fund_use_direction') == '慈善资金')\
            .group({'x': '$user_info.name'}, [{'y': self.ao.summation('$fund_total')}])\
            .sort({'y': -1})\
            .limit(10)
        res = self.query(_filter, "PT_Financial_Account_Directional_Pool")
        return res

    def cop_statistics_item_use_amount_top10_quantity(self, condition, page, count):
        '''慈善项目使用金额排名'''
        _filter = MongoBillFilter()
        _filter.lookup_bill('PT_Financial_Account_Directional_Expend_ltem', 'expenditure_item_id', 'id', 'item')\
            .lookup_bill('PT_Financial_Account_Directional_Pool', 'fund_pool_id', 'id', 'pool')\
            .match_bill(C('pool.fund_use_direction') == '慈善资金')\
            .group({'x': '$item.name'}, [{'y': self.ao.summation('$pool.fund_total')}])\
            .sort({'y': -1})\
            .limit(10)
        res = self.query(_filter, "PT_Financial_Account_Record_Directional")
        return res

    def cop_statistics_time_quantity(self, condition, page, count):
        '''服务次数走势'''
        _filter = self.__org_area()
        _filter.inner_join_bill(
            'PT_Service_Record', 'user_info.id', 'servicer_id', 'service_record')
        _filter = self._group_by_date(
            _filter, '$service_record.start_date', '月')
        _filter.group({'x': '$new_date'}, [{'y': self.ao.summation(1)}])\
               .sort({'x': 1})
        res = self.query(_filter, "PT_Business_Area")
        return res

    def cop_statistics_time_profit_quantity(self, condition, page, count):
        '''服务收益走势'''
        _filter = self.__org_area()
        _filter.inner_join_bill(
            'PT_Service_Record', 'user_info.id', 'servicer_id', 'service_record')
        _filter = self._group_by_date(
            _filter, '$service_record.start_date', '月')
        _filter.group({'x': '$new_date'}, [{'y': self.ao.summation('$service_record.valuation_amount')}])\
               .sort({'x': 1})
        res = self.query(_filter, "PT_Business_Area")
        return res

    def cop_statistics_time_income_quantity(self, condition, page, count):
        '''慈善收入走势'''
        return 'ok'

    def cop_statistics_time_grant_quantity(self, condition, page, count):
        '''慈善发放走势'''
        return 'ok'

    def cop_statistics_time_subsidy_quantity(self, condition, page, count):
        '''补贴发放走势'''
        return 'ok'
